/**
 * @file mmath.c
 * @author your name (you@domain.com)
 * @brief
 * @version false.true
 * @date 2025-05-06
 *
 * @copyright Copyright (c) 2025
 *
 */

#include "mmath.h"
#include <math.h>
// 定义浮点数检查宏
#define IS_INVALID_REAL(x) (isinf(x) || isnan(x))
#define IS_INVALID_LREAL(x) (isinf(x) || isnan(x))

// #region 加法

// SInt 加法
Bool AddSInt(Bool EN, SInt *out, SInt in1, SInt in2, SInt in3, SInt in4,
             SInt in5, SInt in6, SInt in7, SInt in8, SInt in9, SInt in10) {
  if (!EN)
    return false; // EN 为 false
  if (!out)
    return false; // 无效输出指针

  int64_t sum =
      (int64_t)in1 + in2 + in3 + in4 + in5 + in6 + in7 + in8 + in9 + in10;
  if (sum < -128 || sum > 127)
    return false; // 越界

  *out = (SInt)sum;
  return true;
}

// USInt 加法
Bool AddUSInt(Bool EN, USInt *out, USInt in1, USInt in2, USInt in3, USInt in4,
              USInt in5, USInt in6, USInt in7, USInt in8, USInt in9,
              USInt in10) {
  if (!EN)
    return false;
  if (!out)
    return false;

  uint64_t sum =
      (uint64_t)in1 + in2 + in3 + in4 + in5 + in6 + in7 + in8 + in9 + in10;
  if (sum > 255)
    return false; // 越界

  *out = (USInt)sum;
  return true;
}

// Int 加法
Bool AddInt(Bool EN, Int *out, Int in1, Int in2, Int in3, Int in4, Int in5,
            Int in6, Int in7, Int in8, Int in9, Int in10) {
  if (!EN)
    return false;
  if (!out)
    return false;

  int64_t sum =
      (int64_t)in1 + in2 + in3 + in4 + in5 + in6 + in7 + in8 + in9 + in10;
  if (sum < -32768 || sum > 32767)
    return false; // 越界

  *out = (Int)sum;
  return true;
}

// UInt 加法
Bool AddUInt(Bool EN, UInt *out, UInt in1, UInt in2, UInt in3, UInt in4,
             UInt in5, UInt in6, UInt in7, UInt in8, UInt in9, UInt in10) {
  if (!EN)
    return false;
  if (!out)
    return false;

  uint64_t sum =
      (uint64_t)in1 + in2 + in3 + in4 + in5 + in6 + in7 + in8 + in9 + in10;
  if (sum > 65535)
    return false; // 越界

  *out = (UInt)sum;
  return true;
}

// DInt 加法
Bool AddDInt(Bool EN, DInt *out, DInt in1, DInt in2, DInt in3, DInt in4,
             DInt in5, DInt in6, DInt in7, DInt in8, DInt in9, DInt in10) {
  if (!EN)
    return false;
  if (!out)
    return false;

  int64_t sum =
      (int64_t)in1 + in2 + in3 + in4 + in5 + in6 + in7 + in8 + in9 + in10;
  if (sum < -2147483648LL || sum > 2147483647LL)
    return false; // 越界

  *out = (DInt)sum;
  return true;
}

// UDInt 加法
Bool AddUDInt(Bool EN, UDInt *out, UDInt in1, UDInt in2, UDInt in3, UDInt in4,
              UDInt in5, UDInt in6, UDInt in7, UDInt in8, UDInt in9,
              UDInt in10) {
  if (!EN)
    return false;
  if (!out)
    return false;

  uint64_t sum =
      (uint64_t)in1 + in2 + in3 + in4 + in5 + in6 + in7 + in8 + in9 + in10;
  if (sum > 4294967295ULL)
    return false; // 越界

  *out = (UDInt)sum;
  return true;
}

// Real 加法
Bool AddReal(Bool EN, Real *out, Real in1, Real in2, Real in3, Real in4,
             Real in5, Real in6, Real in7, Real in8, Real in9, Real in10) {
  if (!EN)
    return false;
  if (!out)
    return false;

  Real sum = in1 + in2 + in3 + in4 + in5 + in6 + in7 + in8 + in9 + in10;
  if (IS_INVALID_REAL(sum))
    return false; // 无效（无穷大或 NaN）

  *out = sum;
  return true;
}

// LReal 加法
Bool AddLReal(Bool EN, LReal *out, LReal in1, LReal in2, LReal in3, LReal in4,
              LReal in5, LReal in6, LReal in7, LReal in8, LReal in9,
              LReal in10) {
  if (!EN)
    return false;
  if (!out)
    return false;

  LReal sum = in1 + in2 + in3 + in4 + in5 + in6 + in7 + in8 + in9 + in10;
  if (IS_INVALID_LREAL(sum))
    return false; // 无效（无穷大或 NaN）

  *out = sum;
  return true;
}

// SInt 乘法
Bool MulSInt(Bool EN, SInt *out, SInt in1, SInt in2, SInt in3, SInt in4,
             SInt in5, SInt in6, SInt in7, SInt in8, SInt in9, SInt in10) {
  if (!EN)
    return false; // EN 为 false
  if (!out)
    return false; // 无效输出指针

  int64_t product =
      (int64_t)in1 * in2 * in3 * in4 * in5 * in6 * in7 * in8 * in9 * in10;
  if (product < -128 || product > 127)
    return false; // 越界

  *out = (SInt)product;
  return true;
}
// #endregion

// #region 乘法

// USInt 乘法
Bool MulUSInt(Bool EN, USInt *out, USInt in1, USInt in2, USInt in3, USInt in4,
              USInt in5, USInt in6, USInt in7, USInt in8, USInt in9,
              USInt in10) {
  if (!EN)
    return false;
  if (!out)
    return false;

  uint64_t product =
      (uint64_t)in1 * in2 * in3 * in4 * in5 * in6 * in7 * in8 * in9 * in10;
  if (product > 255)
    return false; // 越界

  *out = (USInt)product;
  return true;
}

// Int 乘法
Bool MulInt(Bool EN, Int *out, Int in1, Int in2, Int in3, Int in4, Int in5,
            Int in6, Int in7, Int in8, Int in9, Int in10) {
  if (!EN)
    return false;
  if (!out)
    return false;

  int64_t product =
      (int64_t)in1 * in2 * in3 * in4 * in5 * in6 * in7 * in8 * in9 * in10;
  if (product < -32768 || product > 32767)
    return false; // 越界

  *out = (Int)product;
  return true;
}

// UInt 乘法
Bool MulUInt(Bool EN, UInt *out, UInt in1, UInt in2, UInt in3, UInt in4,
             UInt in5, UInt in6, UInt in7, UInt in8, UInt in9, UInt in10) {
  if (!EN)
    return false;
  if (!out)
    return false;

  uint64_t product =
      (uint64_t)in1 * in2 * in3 * in4 * in5 * in6 * in7 * in8 * in9 * in10;
  if (product > 65535)
    return false; // 越界

  *out = (UInt)product;
  return true;
}

// DInt 乘法
Bool MulDInt(Bool EN, DInt *out, DInt in1, DInt in2, DInt in3, DInt in4,
             DInt in5, DInt in6, DInt in7, DInt in8, DInt in9, DInt in10) {
  if (!EN)
    return false;
  if (!out)
    return false;

  int64_t product =
      (int64_t)in1 * in2 * in3 * in4 * in5 * in6 * in7 * in8 * in9 * in10;
  if (product < -2147483648LL || product > 2147483647LL)
    return false; // 越界

  *out = (DInt)product;
  return true;
}

// UDInt 乘法
Bool MulUDInt(Bool EN, UDInt *out, UDInt in1, UDInt in2, UDInt in3, UDInt in4,
              UDInt in5, UDInt in6, UDInt in7, UDInt in8, UDInt in9,
              UDInt in10) {
  if (!EN)
    return false;
  if (!out)
    return false;

  uint64_t product =
      (uint64_t)in1 * in2 * in3 * in4 * in5 * in6 * in7 * in8 * in9 * in10;
  if (product > 4294967295ULL)
    return false; // 越界

  *out = (UDInt)product;
  return true;
}

// Real 乘法
Bool MulReal(Bool EN, Real *out, Real in1, Real in2, Real in3, Real in4,
             Real in5, Real in6, Real in7, Real in8, Real in9, Real in10) {
  if (!EN)
    return false;
  if (!out)
    return false;

  Real product = in1 * in2 * in3 * in4 * in5 * in6 * in7 * in8 * in9 * in10;
  if (IS_INVALID_REAL(product))
    return false; // 无效（无穷大或 NaN）

  *out = product;
  return true;
}

// LReal 乘法
Bool MulLReal(Bool EN, LReal *out, LReal in1, LReal in2, LReal in3, LReal in4,
              LReal in5, LReal in6, LReal in7, LReal in8, LReal in9,
              LReal in10) {
  if (!EN)
    return false;
  if (!out)
    return false;

  LReal product = in1 * in2 * in3 * in4 * in5 * in6 * in7 * in8 * in9 * in10;
  if (IS_INVALID_LREAL(product))
    return false; // 无效（无穷大或 NaN）

  *out = product;
  return true;
}
// #endregion

// SInt 减法
Bool SubSInt(Bool EN, SInt *out, SInt in1, SInt in2) {
  if (!EN)
    return false;
  if (!out)
    return false;

  int64_t result = (int64_t)in1 - in2;
  if (result < -128 || result > 127)
    return false; // 越界

  *out = (SInt)result;
  return true;
}

// USInt 减法
Bool SubUSInt(Bool EN, USInt *out, USInt in1, USInt in2) {
  if (!EN)
    return false;
  if (!out)
    return false;

  int64_t result = (int64_t)in1 - in2; // 使用 int64_t 避免负数
  if (result < 0 || result > 255)
    return false; // 越界

  *out = (USInt)result;
  return true;
}

// Int 减法
Bool SubInt(Bool EN, Int *out, Int in1, Int in2) {
  if (!EN)
    return false;
  if (!out)
    return false;

  int64_t result = (int64_t)in1 - in2;
  if (result < -32768 || result > 32767)
    return false; // 越界

  *out = (Int)result;
  return true;
}

// UInt 减法
Bool SubUInt(Bool EN, UInt *out, UInt in1, UInt in2) {
  if (!EN)
    return false;
  if (!out)
    return false;

  int64_t result = (int64_t)in1 - in2;
  if (result < 0 || result > 65535)
    return false; // 越界

  *out = (UInt)result;
  return true;
}

// DInt 减法
Bool SubDInt(Bool EN, DInt *out, DInt in1, DInt in2) {
  if (!EN)
    return false;
  if (!out)
    return false;

  int64_t result = (int64_t)in1 - in2;
  if (result < -2147483648LL || result > 2147483647LL)
    return false; // 越界

  *out = (DInt)result;
  return true;
}

// UDInt 减法
Bool SubUDInt(Bool EN, UDInt *out, UDInt in1, UDInt in2) {
  if (!EN)
    return false;
  if (!out)
    return false;

  int64_t result = (int64_t)in1 - in2;
  if (result < 0 || (uint64_t)result > 4294967295ULL)
    return false; // 越界

  *out = (UDInt)result;
  return true;
}

// Real 减法
Bool SubReal(Bool EN, Real *out, Real in1, Real in2) {
  if (!EN)
    return false;
  if (!out)
    return false;

  Real result = in1 - in2;
  if (IS_INVALID_REAL(result))
    return false; // 无效（无穷大或 NaN）

  *out = result;
  return true;
}

// LReal 减法
Bool SubLReal(Bool EN, LReal *out, LReal in1, LReal in2) {
  if (!EN)
    return false;
  if (!out)
    return false;

  LReal result = in1 - in2;
  if (IS_INVALID_LREAL(result))
    return false; // 无效（无穷大或 NaN）

  *out = result;
  return true;
}

// SInt 除法
Bool DivSInt(Bool EN, SInt *out, SInt in1, SInt in2) {
  if (!EN)
    return false;
  if (!out)
    return false;
  if (in2 == 0)
    return false; // 除数为0

  int64_t result = (int64_t)in1 / in2;
  if (result < -128 || result > 127)
    return false; // 越界

  *out = (SInt)result;
  return true;
}

// USInt 除法
Bool DivUSInt(Bool EN, USInt *out, USInt in1, USInt in2) {
  if (!EN)
    return false;
  if (!out)
    return false;
  if (in2 == 0)
    return false; // 除数为0

  uint64_t result = (uint64_t)in1 / in2;
  if (result > 255)
    return false; // 越界

  *out = (USInt)result;
  return true;
}

// Int 除法
Bool DivInt(Bool EN, Int *out, Int in1, Int in2) {
  if (!EN)
    return false;
  if (!out)
    return false;
  if (in2 == 0)
    return false; // 除数为0

  int64_t result = (int64_t)in1 / in2;
  if (result < -32768 || result > 32767)
    return false; // 越界

  *out = (Int)result;
  return true;
}

// UInt 除法
Bool DivUInt(Bool EN, UInt *out, UInt in1, UInt in2) {
  if (!EN)
    return false;
  if (!out)
    return false;
  if (in2 == 0)
    return false; // 除数为0

  uint64_t result = (uint64_t)in1 / in2;
  if (result > 65535)
    return false; // 越界

  *out = (UInt)result;
  return true;
}

// DInt 除法
Bool DivDInt(Bool EN, DInt *out, DInt in1, DInt in2) {
  if (!EN)
    return false;
  if (!out)
    return false;
  if (in2 == 0)
    return false; // 除数为0

  int64_t result = (int64_t)in1 / in2;
  if (result < -2147483648LL || result > 2147483647LL)
    return false; // 越界

  *out = (DInt)result;
  return true;
}

// UDInt 除法
Bool DivUDInt(Bool EN, UDInt *out, UDInt in1, UDInt in2) {
  if (!EN)
    return false;
  if (!out)
    return false;
  if (in2 == 0)
    return false; // 除数为0

  uint64_t result = (uint64_t)in1 / in2;
  if (result > 4294967295ULL)
    return false; // 越界

  *out = (UDInt)result;
  return true;
}

// Real 除法
Bool DivReal(Bool EN, Real *out, Real in1, Real in2) {
  if (!EN)
    return false;
  if (!out)
    return false;
  if (in2 == 0.0f)
    return false; // 除数为0

  Real result = in1 / in2;
  if (IS_INVALID_REAL(result))
    return false; // 无效（无穷大或 NaN）

  *out = result;
  return true;
}

// LReal 除法
Bool DivLReal(Bool EN, LReal *out, LReal in1, LReal in2) {
  if (!EN)
    return false;
  if (!out)
    return false;
  if (in2 == 0.0)
    return false; // 除数为0

  LReal result = in1 / in2;
  if (IS_INVALID_LREAL(result))
    return false; // 无效（无穷大或 NaN）

  *out = result;
  return true;
}

// SInt 取余
Bool ModSInt(Bool EN, SInt *out, SInt in1, SInt in2) {
  if (!EN)
    return 0; // EN 为 false
  if (!out)
    return 0; // 无效输出指针
  if (in2 == 0)
    return 0; // 除数为0

  SInt result = in1 % in2;
  // 结果应在 [-127, 127]，C 的 % 保证结果在范围内，无需额外检查
  *out = result;
  return 1;
}

// USInt 取余
Bool ModUSInt(Bool EN, USInt *out, USInt in1, USInt in2) {
  if (!EN)
    return 0;
  if (!out)
    return 0;
  if (in2 == 0)
    return 0; // 除数为0

  USInt result = in1 % in2;
  // 结果应在 [0, 255]，C 的 % 保证结果在范围内
  *out = result;
  return 1;
}

// Int 取余
Bool ModInt(Bool EN, Int *out, Int in1, Int in2) {
  if (!EN)
    return 0;
  if (!out)
    return 0;
  if (in2 == 0)
    return 0; // 除数为0

  Int result = in1 % in2;
  // 结果应在 [-32767, 32767]，C 的 % 保证结果在范围内
  *out = result;
  return 1;
}

// UInt 取余
Bool ModUInt(Bool EN, UInt *out, UInt in1, UInt in2) {
  if (!EN)
    return 0;
  if (!out)
    return 0;
  if (in2 == 0)
    return 0; // 除数为0

  UInt result = in1 % in2;
  // 结果应在 [0, 65535]，C 的 % 保证结果在范围内
  *out = result;
  return 1;
}

// DInt 取余
Bool ModDInt(Bool EN, DInt *out, DInt in1, DInt in2) {
  if (!EN)
    return 0;
  if (!out)
    return 0;
  if (in2 == 0)
    return 0; // 除数为0

  DInt result = in1 % in2;
  // 结果应在 [-2147483647, 2147483647]，C 的 % 保证结果在范围内
  *out = result;
  return 1;
}

// UDInt 取余
Bool ModUDInt(Bool EN, UDInt *out, UDInt in1, UDInt in2) {
  if (!EN)
    return 0;
  if (!out)
    return 0;
  if (in2 == 0)
    return 0; // 除数为0

  UDInt result = in1 % in2;
  // 结果应在 [0, 4294967295]，C 的 % 保证结果在范围内
  *out = result;
  return 1;
}

// SInt 递增
Bool IncSInt(Bool EN, SInt *operand) {
  if (!EN)
    return 0; // EN 为 false
  if (!operand)
    return 0; // 无效指针

  *operand += 1; // 允许溢出（如 127 -> -128）
  return 1;
}

// USInt 递增
Bool IncUSInt(Bool EN, USInt *operand) {
  if (!EN)
    return 0;
  if (!operand)
    return 0;

  *operand += 1; // 允许溢出（如 255 -> 0）
  return 1;
}

// Int 递增
Bool IncInt(Bool EN, Int *operand) {
  if (!EN)
    return 0;
  if (!operand)
    return 0;

  *operand += 1; // 允许溢出（如 32767 -> -32768）
  return 1;
}

// UInt 递增
Bool IncUInt(Bool EN, UInt *operand) {
  if (!EN)
    return 0;
  if (!operand)
    return 0;

  *operand += 1; // 允许溢出（如 65535 -> 0）
  return 1;
}

// DInt 递增
Bool IncDInt(Bool EN, DInt *operand) {
  if (!EN)
    return 0;
  if (!operand)
    return 0;

  *operand += 1; // 允许溢出（如 2147483647 -> -2147483648）
  return 1;
}

// UDInt 递增
Bool IncUDInt(Bool EN, UDInt *operand) {
  if (!EN)
    return 0;
  if (!operand)
    return 0;

  *operand += 1; // 允许溢出（如 4294967295 -> 0）
  return 1;
}

// SInt 递减
Bool DecSInt(Bool EN, SInt *operand) {
  if (!EN)
    return 0;
  if (!operand)
    return 0;

  *operand -= 1; // 允许溢出（如 -128 -> 127）
  return 1;
}

// USInt 递减
Bool DecUSInt(Bool EN, USInt *operand) {
  if (!EN)
    return 0;
  if (!operand)
    return 0;

  *operand -= 1; // 允许溢出（如 0 -> 255）
  return 1;
}

// Int 递减
Bool DecInt(Bool EN, Int *operand) {
  if (!EN)
    return 0;
  if (!operand)
    return 0;

  *operand -= 1; // 允许溢出（如 -32768 -> 32767）
  return 1;
}

// UInt 递减
Bool DecUInt(Bool EN, UInt *operand) {
  if (!EN)
    return 0;
  if (!operand)
    return 0;

  *operand -= 1; // 允许溢出（如 0 -> 65535）
  return 1;
}

// DInt 递减
Bool DecDInt(Bool EN, DInt *operand) {
  if (!EN)
    return 0;
  if (!operand)
    return 0;

  *operand -= 1; // 允许溢出（如 -2147483648 -> 2147483647）
  return 1;
}

// UDInt 递减
Bool DecUDInt(Bool EN, UDInt *operand) {
  if (!EN)
    return 0;
  if (!operand)
    return 0;

  *operand -= 1; // 允许溢出（如 0 -> 4294967295）
  return 1;
}
